package edu.utexas.mapreduce;

import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.CommandLine;


public class MapReduce {

	public static CommandLine line;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//
		// Command line options
		//
		Options options = new Options();	
		options.addOption(CommandLineParameters.Help, false, "print this message");
		options.addOption(CommandLineParameters.Client, false, "submit job to mapreduce server");
		options.addOption(CommandLineParameters.Server, false, "start mapreduce server");
		options.addOption(CommandLineParameters.Jar, true, "[client] jar containing  mapreduce application classes");
		options.addOption(CommandLineParameters.Input, true, "[client] input file or directory for mapreduce job");
		options.addOption(CommandLineParameters.Output, true, "[client] output directory for mapreduce job");
		options.addOption(CommandLineParameters.Url, true, "[client] address of the map reduce server");
		options.addOption(CommandLineParameters.BaseDir, true, "[server] working directory for mapreduce server");
		options.addOption(CommandLineParameters.Map, true, "[client] name of application map class");
		options.addOption(CommandLineParameters.Reduce, true, "[client] name of application reduce class");
		options.addOption(CommandLineParameters.JobFile, true, "[client] path to job description file");
		options.addOption(CommandLineParameters.HTTPPort, true, "[server] port number the HTTP server will use (defaults to 8000)");
		options.addOption(CommandLineParameters.ProcessID, true, "[server] process ID");
		options.addOption(CommandLineParameters.ServerList, true, "[server] path to file listing all mapreduce server IPC addresses");
		options.addOption(CommandLineParameters.RequesterEmail, true, "[client] optional email address to send done notification");
		
		
		CommandLineParser parser = new GnuParser();
	    try {
	        // parse the command line arguments
	        line = parser.parse(options, args);

	        if (line.hasOption(CommandLineParameters.Server)) {
	        	//launch server
	        	ServerConfig config = new ServerConfig();
	        	if (line.hasOption(CommandLineParameters.BaseDir)){
	        		config.baseDir = line.getOptionValue(CommandLineParameters.BaseDir);
	        		config.HTTPport = Integer.parseInt(line.getOptionValue(CommandLineParameters.HTTPPort, Integer.toString(config.HTTPport)));
	        		config.processID = Integer.parseInt(line.getOptionValue(CommandLineParameters.ProcessID, Integer.toString(config.processID)));
	        		config.serverList = line.getOptionValue(CommandLineParameters.ServerList, null);
	        		ServerMapReduce server = new ServerMapReduce(config);
	        		server.run();
	        	}
	        	else{
	        		System.out.println("Need to specify a base directory");
	        	}
	        	return;
	        }
	        
	        if (line.hasOption(CommandLineParameters.Client)) {
	        	//launch client
	        	//TODO: Create a client configuration class just like the server has, instead of passing the command line to the client
        		ClientMapReduce client = new ClientMapReduce(line);
        		client.run();
	        	return;
	        }
	        
			HelpFormatter formatter = new HelpFormatter();
			formatter.printHelp("mapreduce", options);
	    }
	    catch( ParseException exp ) {
	        // oops, something went wrong
	        System.err.println( "Parsing failed.  Reason: " + exp.getMessage() );
	    }
	}

}
